#include "client.h"

void getMD5(int fd, char* result) {
    int ret = 0;
    char buff[1000] = {0};
    MD5_CTX ctx;
    MD5_Init(&ctx);//初始化MD5的结构体
    while (1) {
        memset(buff, 0, sizeof(buff));
        //读取文件中的一段内容
        ret = read(fd, buff, sizeof(buff));
        if (ret == 0) {
            break;
        }

        //对每一段内容调用更新函数
        MD5_Update(&ctx, buff, ret);
    }
    unsigned char md[16] = {0};
    MD5_Final(md, &ctx);
    for (int i = 0; i < 16; i++) {
        char frag[3] = {0};
        sprintf(frag, "%02x", md[i]);
        strcat(result, frag);
    }

}

void putsCommand(client_task_t * task){
    // 处理 puts 命令
    char filename[100] = {0};
    strcpy(filename, task->train.buff);
    int fd = open(filename, O_RDWR);
    if (fd == -1) {
        error(1, errno, "open");
    }
    //获得md5码
    char result[33] = {0};
    getMD5(fd, result);
    puts(result);
    CmdType x;
    task->train.len = strlen(result);
    strcpy(task->train.buff, result);
    x = (CmdType)-1;
    sendn(task->peerfd, &task->train, 4 + 4 + task->train.len);
    /* puts(result); */
    //将md5发送给服务器，看文件是否已经存在
    //如果已经存在，则采用秒传技术,并在服务端添加记录
    //如果不存在，则继续传输，并在服务端添加记录
    //接收用户端发送的类型判断需要进行哪种传输方式
    //用x来接收类型
    recvn(task->peerfd, &x, sizeof(x));
    if (x == CMD_TYPE_SECOND_TRANSMIT) {
        //进行秒传操作
        printf("进行秒传!\n");
        printf("send %s over\n", filename);
    } else {//进行正常传输操作
    //断点重传
    off_t lenhalf;
    recvn(task->peerfd, &lenhalf, sizeof(lenhalf));

    if (lenhalf != 0) {
        printf("断点续传\n");
    }
    printf("offset = %ld\n", lenhalf);

    //发送文件的总长度
    struct stat st;
    memset(&st, 0, sizeof(st));
    fstat(fd, &st);
    printf("filelength: %ld\n", st.st_size);//off_t
    printf("sizeof(st.st_size): %ld\n", sizeof(st.st_size));
    sendn(task->peerfd, &st.st_size, sizeof(st.st_size));

    //续传的计算
    off_t length = st.st_size - lenhalf;

    if (length >= 100 * 1024 * 1024) {
        puts("大文件传输");
        int ret = sendfile(task->peerfd, fd, &lenhalf, length);
        printf("ret: %d, send file over.\n", ret);

    } else {//小文件采用循环发送
            //4将文件偏移到文件
        if(lseek(fd, lenhalf, SEEK_SET) == -1){
            error(1,errno,"lseek ");
        }

        while (1) {
            memset(&task->train, 0, sizeof(task->train));
            int ret = read(fd, task->train.buff, sizeof(task->train.buff));
            if (ret == 0) {
                //文件读取完了,退出循环并通知对方退出
                task->train.len = 0;
                sendn(task->peerfd, &task->train.len, 4);
                break;
            }
            task->train.len = ret;
            task->train.type =(CmdType)(-1);
            ret = sendn(task->peerfd, &task->train, 4 + 4 + task->train.len);
            if (ret == -1) {
                break;//发生错误
            }
        }//while
     }
    close(fd);
    printf("send %s over\n", filename);
  }//秒传地方的else

}
